package cn.zebra.dev.config.spring.exception;

import cn.zebra.dev.common.restful.Result;
import com.sun.media.sound.InvalidFormatException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;

import java.io.IOException;
import java.sql.SQLException;
import java.sql.SQLSyntaxErrorException;
import java.util.concurrent.TimeoutException;
import java.util.stream.Collectors;

/**
 * 异常处理机制
 *
 * @author runnable@sina.cn
 */
@RestControllerAdvice
public class HandlerController {
    private final Logger LOG = LoggerFactory.getLogger(getClass());

    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(BindException.class)
    public Result bindExceptionHandler(final BindException e) {
        String message = e.getBindingResult().getAllErrors().stream().map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining());
        return Result.error(message);
    }

    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result handler(final MethodArgumentNotValidException e) {
        String message = e.getBindingResult().getFieldErrors().get(0).getDefaultMessage();
        return Result.error(message);
    }

    @ExceptionHandler(NullPointerException.class)
    public Result nullPointerException(NullPointerException e) {
        LOG.error(e.getMessage(), e);
        return Result.error("服务器异常!");
    }

    @ExceptionHandler(TimeoutException.class)
    public Result timeoutException(TimeoutException e) {
        LOG.error(e.getMessage(), e);
        return Result.error("请求超时!");
    }

    @ExceptionHandler(IOException.class)
    public Result ioException(IOException e) {
        LOG.error(e.getMessage(), e);
        return Result.error("服务器异常!");
    }

    @ExceptionHandler(SQLSyntaxErrorException.class)
    public Result sqlSyntaxErrorException(SQLSyntaxErrorException e) {
        LOG.error(e.getMessage(), e);
        return Result.error("服务器异常!");
    }

    @ExceptionHandler(HttpMessageNotReadableException.class)
    public Result httpMessageNotReadableException(HttpMessageNotReadableException e) {
        LOG.error(e.getMessage(), e);
        return Result.error("传递参数格式不合法!");
    }

    @ExceptionHandler(MethodArgumentTypeMismatchException.class)
    public Result methodArgumentTypeMismatchException(MethodArgumentTypeMismatchException e) {
        LOG.error(e.getMessage(), e);
        return Result.error("传递参数格式不合法!");
    }

    @ExceptionHandler(InvalidFormatException.class)
    public Result invalidFormatException(InvalidFormatException e) {
        LOG.error(e.getMessage(), e);
        return Result.error("传递参数格式不合法!");
    }

    @ExceptionHandler(RuntimeException.class)
    public Result runtimeException(RuntimeException e) {
        return Result.error(e.getMessage());
    }

    @ExceptionHandler(SQLException.class)
    public Result sqlException(SQLException e) {
        LOG.error(e.getMessage(), e);
        return Result.error("服务器异常!");
    }

    @ExceptionHandler(ClassCastException.class)
    public Result classCastException(ClassCastException e) {
        LOG.error(e.getMessage(), e);
        return Result.error("服务器异常!");
    }
}
